/**
	SUNNY Project, Anyang Normal University, IMP-CAS
	\brief This code is for tackling the full configuration interaction
	in many-body problems which is a common question in many-body problems
	\since 2020/01/31
	\date Last modified: 2020/01/31
	\copyright 2020-2022, SUN Yazhou
  \copyright SUNNY project, Anyang Normal University, IMP-CAS
*/

#include <iostream>
#include "TAMBSDManager.h"
#include "TADiagonalize.h"
#include "TAZBM.h"
#include "TATreeCol.h"
#include "TALanczos.h"
#include "TASparseMatrix.h"
#include "TASparseVec.h"
#include "TASPStateManager.h"
#include "TAMBSDManager.h"
#include "TAParaManager.h"

using std::cout;
using std::endl;

#define JACOB
// #define TRIQL
// #define D_LCZS
#define LCZS // Lanczos with TASparseVec and TASparseMatrix

int main(){
	PARA->SetBaseDir("config/fci");
	TAZBM *zbm = new TAZBM("zbm.yaml");
	const int nb = zbm->GetNBasis();
	TASPStateManager::Instance()->Print();
	TAMBSDManager::Instance()->Print();
	// H->Print();
	// H->PrintInPic("zbm");

	// getchar();

	matrix z(nb, nb);
	double d[nb]; for(auto &t : d) t = -9999.;

#ifdef JACOB

	matrix *H = zbm->Matrix();
	TADiagonalize::JacobiSort(*H, nb, d, z);
	cout << endl << endl;
	for(int i = 0; i < nb; i++) cout << d[i] << " ";
	cout << endl << endl;
	// z.PrintInPic("EigenVec");
	// z.Print();

#endif

#ifdef TRIQL

	matrix *H = zbm->Matrix();
	TADiagonalize::TridiagQLSort(*H, nb, d);
	cout << endl;
	for(int i = 0; i < nb; i++) cout << d[i] << " ";
	cout << endl;
	// H->PrintInPic("EigenVec");

#endif

#ifdef D_LCZS

	matrix *H = zbm->Matrix();
	TADiagonalize::LanczosPurge(*H, nb, d, z, 3);
	cout << endl << endl;
	for(int i = 0; i < nb; i++) cout << d[i] << " ";
	cout << endl << endl;
	// z.PrintInPic("EigenVec");

#endif

#ifdef _ROOT_
#ifdef LCZS

	// Using Lanczos method //
	TASparseMatrix v;
	TALanczos::PurgeRestart(zbm,d,v, 5);

	cout << endl;
	for(int i = 0; i < nb; i++) cout << d[i] << " ";
	cout << endl;
	v.Print();

	TATreeCol::CloseFile();
#endif
#endif

	return 0;

	//
	// // diagonalize using TALanczos //
	// const short n = zbm->GetNBasis() < 30 ? zbm->GetNBasis() : 30;
	// TASparseMatrix z; double d[n*2]{};
	// TALanczos::PurgeRestart(*zbm, d, z, n);
	//
	// for(int i = 0; i < n; i++) cout << d[i] << endl;
	// z.Print();
	//
	// z.Save();
	// TATreeCol::CloseFile();
	// return 0;
} // end main function
